package com.gopay.common.security.encryptiondecryption;

import java.lang.reflect.Field;

import org.apache.commons.lang.StringUtils;
import org.springframework.util.ReflectionUtils;

import com.gopay.common.domain.pg.PgGenOrderTransDtl;

/**
 * des加解密工具类（处理带存量数据）
 * @DesUtilWithStockOfData.java
 * @author dongdh
 * @2016年5月17日 下午7:12:21  www.gopay.com.cn Inc.All rights reserved.
 */
public class DesUtilWithStockOfData {
    
    private static final String MARK = "M_";
    
    
    private static final String[] DEFAULT_FIELD = new String[]{"creditCardExpired", "buyerRealBankAcctNum", "buyerRealMobile", "buyerRealName", "buyerRealCertNo"};
    
    
    /**
     * 加密
     * @param str
     * @return
     */
    public static String encrypt(String str) {
        
        return encrpyt(str, false);
    }
    
    public static String encrpyt(String str, boolean isStock) {
        if (StringUtils.isNotEmpty(str)) {
            Encrypt enc;
            try {
                enc = new Encrypt();
                str = enc.encrypt(str);
                if (isStock) {
                    return MARK + str;
                }
                return str;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return str;
    }
    
    /**
     * 解密 ，自行判断是否处理存量
     * @param str
     * @return
     */
    public static String decrypt(String str, boolean isStock) {
        if (StringUtils.isNotEmpty(str)) {
            Decrypt dec;
            try {
                dec = new Decrypt();
                if (isStock) {
                    if (str.startsWith(MARK)) {
                        str = str.replace(MARK, "");
                        return dec.decrypt(str);
                    } 
                    return str;
                }
                return dec.decrypt(str);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return str;
    }
    
    /**
     * 对象加密
     * @param obj
     * @param fields
     */
    public static void encrypt(Object obj, String...fields) {
        encrypt(obj, false, fields);
    }
    
    /**
     * 加密
     * @param obj
     * @param isStock
     * @param fields
     */
    public static  void encrypt(Object obj, boolean isStock, String...fields) {
        if (obj != null) {
            
            if (fields == null || fields.length == 0) {
                fields = DEFAULT_FIELD;
            }
            
            for (int i = 0; i < fields.length; i++) {
                Field field = ReflectionUtils.findField(obj.getClass(), fields[i]);
                
                if (field != null) {
                    try {
                        field.setAccessible(true);
                        Object val = field.get(obj);
                        //加密数据
                        if (val == null) {
                            continue;
                        }
                        val = encrpyt(val.toString(), isStock);
                        ReflectionUtils.setField(field, obj, val);
                        
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    /**
     * 解密
     * @param obj
     * @param isStock
     * @param fields
     */
    public static void decrypt(Object obj, boolean isStock,  String...fields) {
        if (obj != null) {
            
            if (fields == null || fields.length == 0) {
                fields = DEFAULT_FIELD;
            }
            
            for (int i = 0; i < fields.length; i++) {
                Field field = ReflectionUtils.findField(obj.getClass(), fields[i]);
                
                if (field != null) {
                    try {
                        field.setAccessible(true);
                        Object val = field.get(obj);
                        if (val == null) {
                            continue;
                        }
                        val = decrypt(val.toString(), isStock);
                        ReflectionUtils.setField(field, obj, val);
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    public static void main(String[] args) {
        PgGenOrderTransDtl dtl =  new PgGenOrderTransDtl();
        
        dtl.setBuyerRealName("ddh");
        
        DesUtilWithStockOfData.encrypt(dtl, true);       
        System.out.println(dtl.getBuyerRealName());
        
        
        System.out.println(decrypt("M_0198c1d8adce35d5", true));
        
    }

}
